import sys
import serial
import serial.tools.list_ports
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QComboBox, QPushButton, QTextEdit, QGridLayout, QMessageBox 
from PyQt5.QtCore import Qt, QTimer, QEventLoop
from PyQt5.QtGui import QIcon
import pyautogui

class SerialListener(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('扫码枪:v1.0')
        self.setGeometry(100, 100, 400, 300)
        self.setWindowIcon(QIcon('lcon.ico'))

        # 创建布局
        layout = QGridLayout()

        # 串口选择下拉菜单
        self.combo_port = QComboBox()
        ports = [port.device for port in serial.tools.list_ports.comports()]
        self.combo_port.addItems(ports)
        layout.addWidget(QLabel('选择串口:'), 0, 0)
        layout.addWidget(self.combo_port, 0, 1)

        # 波特率选择下拉菜单
        self.combo_baudrate = QComboBox()
        self.combo_baudrate.addItems(['115200'])
        layout.addWidget(QLabel('波特率:'), 1, 0)
        layout.addWidget(self.combo_baudrate, 1, 1)

        # 开始/停止按钮
        self.btn_start_stop = QPushButton('开始监听')
        self.btn_start_stop.clicked.connect(self.toggle_listener)
        layout.addWidget(self.btn_start_stop, 2, 0, 1, 2)

        # 文本显示区域
        self.text_area = QTextEdit(readOnly=True)
        layout.addWidget(self.text_area, 3, 0, 1, 2)

        # 设置布局
        self.setLayout(layout)

        # 串口实例
        self.serial_instance = None

        # 监听定时器
        self.timer = QTimer()
        self.timer.timeout.connect(self.read_serial)

    def toggle_listener(self):
        if self.btn_start_stop.text() == '开始监听':
            self.start_listener()
        else:
            self.stop_listener()

    def start_listener(self):
        port = self.combo_port.currentText()
        baudrate = int(self.combo_baudrate.currentText())
        try:
            self.serial_instance = serial.Serial(port, baudrate, timeout=1)
            self.btn_start_stop.setText('停止监听')
            self.timer.start(100)  # 每100毫秒检查一次串口
            QApplication.processEvents(QEventLoop.ExcludeUserInputEvents)  # 立即刷新GUI
        except serial.SerialException as e:
            self.text_area.append('Error: {}'.format(str(e)))

    def stop_listener(self):
        self.timer.stop()
        try:
            self.serial_instance.close()
        except Exception as e:
            self.text_area.append('Error closing serial port: {}'.format(str(e)))
        self.btn_start_stop.setText('开始监听')
        QApplication.processEvents(QEventLoop.ExcludeUserInputEvents)  # 立即刷新GUI

    def read_serial(self):
        if self.serial_instance and self.serial_instance.is_open:
            try:
                data = self.serial_instance.readline().decode('utf-8', errors='replace').strip()
                if data:
                    # 使用 pyautogui 将数据写入当前活动窗口的输入框
                    pyautogui.typewrite(data)
                    # 按下回车键
                    pyautogui.press('enter')
                    # 在文本显示区域显示数据
                    self.text_area.append(data)
            except serial.SerialException as e:
                self.text_area.append('Error: {}'.format(str(e)))
                self.stop_listener()
            except Exception as e:
                self.text_area.append('Unexpected error: {}'.format(str(e)))
                self.stop_listener()


    def closeEvent(self, event):
        html_text = (
        "<html><body>"
        "<p>确定退出？</p>"
        "<p>Gitee链接：<br>"
        "<a href='https://gitee.com/DaiJunior_1/Demo_1'>点击访问示例</a>.</p>"
        "</body></html>"
    )

        # 创建一个 QMessageBox 实例并设置属性
        msg_box = QMessageBox(self)
        msg_box.setWindowTitle('退出')
        msg_box.setText(html_text)
        msg_box.setTextFormat(Qt.RichText)  # 设置文本格式为富文本
        msg_box.setTextInteractionFlags(Qt.LinksAccessibleByMouse)  # 允许鼠标交互链接
        msg_box.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        msg_box.setDefaultButton(QMessageBox.No)

    # 显示消息框并获取结果
        reply = msg_box.exec_()

        if reply == QMessageBox.Yes:
        # 用户点击了“是”，关闭程序
            event.accept()
        else:
        # 用户点击了“否”，取消关闭程序
            event.ignore()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = SerialListener()
    window.show()
    sys.exit(app.exec_())